home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
PCTAGS15.ARJ
/
TAGIO.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-05
|
13KB
|
363 lines
/*
EPSHeader
File: tagio.c
Author: J. Kercheval
Created: Wed, 07/17/1991 21:48:14
*/
/*
EPSRevision History
J. Kercheval Sun, 08/18/1991 20:49:44 add fill_buffer()
J. Kercheval Tue, 09/03/1991 23:25:13 add buffer_offset to fill_buffer()
J. Kercheval Thu, 09/05/1991 20:13:01 add MergeFile()
J. Kercheval Tue, 09/10/1991 23:55:47 add calls to external_cleanup() when exiting
J. Kercheval Tue, 09/17/1991 19:41:16 add support for case_sensitive flag
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <io.h>
#include "tagio.h"
#include "log.h"
/* external_cleanup() is used on exit(1) for internal error */
extern void external_cleanup(void);
/*----------------------------------------------------------------------------
*
* FillBuffer() fills the passed buffer parameter with bufsize characters
* (or as many as are available) and places and null character '\0' at the
* end of the buffer. This routine returns TRUE if successful and FALSE if
* eof(infile) is true. Note: if a bufsize parameter is passed and the read
* is successful for bufsize characters, then buffer[bufsize] will be
* overwritten with the null character. Do not pass a bufsize the maximum
* size of the buffer. This null terminated buffering scheme assumes the
* source file has no null character embedded within it.
*
---------------------------------------------------------------------------*/
BOOLEAN FillBuffer(FILE * infile, char *buffer, long int bufsize)
{
long int size;
/* init buffer */
*buffer = '\0';
/* return if end of file */
if (feof(infile))
return FALSE;
/* read the buffer from the file */
size = (long int) fread((void *) buffer, (size_t) sizeof(unsigned char),
(size_t) bufsize, infile);
/* place the end of buffer mark and return success */
buffer[size] = '\0';
return TRUE;
}
/*----------------------------------------------------------------------------
*
* GetLine will read a line not to exceed n-1 chars from f and will return
* true if any characters parsed
*
---------------------------------------------------------------------------*/
BOOLEAN GetLine(FILE * f, char *line, int n)
{
int i; /* looping variable (size of line) */
char c; /* temporary character variable */
/* check for end of file */
if (feof(f))
return FALSE;
for (i = 0, c = '\0'; !feof(f) && c != '\n' && i < n - 1; i++) {
/* get next char */
c = (char) fgetc(f);
/* check for end of line due to n-1th character read */
if (i == n - 2) {
log_message("# getline() -- long line encountered - truncating");
do {
c = (char) fgetc(f);
} while (!feof(f) && c != '\n');
}
/* write the character to the line */
line[i] = c;
}
/* zero length string and end of file return FALSE */
if (feof(f) && i == 1)
return FALSE;
/* write end of line and return */
line[i - 1] = '\0';
return TRUE;
}
/*----------------------------------------------------------------------------
*
* OutputTag() places the tag in the correct format into the output stream
*
---------------------------------------------------------------------------*/
void OutputTag(FILE * outfile, char *line, char *symbol, char *infname,
long int line_number, long int char_number, Flags * flags)
{
/* epsilon style output */
if (flags->oe) {
fprintf(outfile, "%s;%s;%ld\n", symbol, infname, char_number);
return;
}
/* GNU style output */
if (flags->og) {
fprintf(outfile, "%s\t%s\t/^%s$/\n", symbol, infname, line);
return;
}
/* spaces delimited output */
if (flags->os) {
fprintf(outfile, "%s %s %ld\n", symbol, infname, line_number);
return;
}
/* MicroSoft Error format */
if (flags->om) {
fprintf(outfile, "%s %s(%ld)\n", symbol, infname, line_number);
return;
}
/* not reached */
log_message("# OutputTag -- internal error - continuing");
return;
}
/*----------------------------------------------------------------------------
*
* MergeFile() will take the temporary file and merge it into the potentially
* existing tag file. During the merge, any tags from the input files which
* were processed during this session will be deleted from the tag file to
* prevent innaccurate tagging information.
*
---------------------------------------------------------------------------*/
#define MAX_TAGFILE_LINE_LENGTH 4096
#define MAXPATH 80
void MergeFile(char *input_filename, char *output_filename,
ArgList arglist, Flags * flags)
{
FILE *input_stream; /* file pointer used for input */
FILE *new_tag_stream; /* file pointer used by new tag stream */
FILE *output_stream; /* file pointer used for output */
char line1[MAX_TAGFILE_LINE_LENGTH]; /* line for new tag file */
char line2[MAX_TAGFILE_LINE_LENGTH]; /* line for old tag file */
char tag_filename[MAXPATH]; /* intermediate used to purge old tags */
char delim[] = " \t;("; /* list of valid delimiters for tag format */
char *tmp_filename; /* intermediate file name */
char *token_start; /* pointer to interesting tokens on purge */
int token_length; /* length of token at token_start */
int compare; /* the results of a stricmp() */
BOOLEAN file1ret; /* true while new tag file in not at EOF */
BOOLEAN file2ret; /* true while old tag file in not at EOF */
if (access(output_filename, 00)) {
/* open the new tags file for read */
if ((new_tag_stream = fopen(input_filename, "r")) ==
(FILE *) NULL) {
log_message("# MergeFile() -- error opening input file");
external_cleanup();
exit(1);
}
/* open the tag output file for write */
if ((output_stream = fopen(output_filename, "w")) ==
(FILE *) NULL) {
log_message("# MergeFile() -- error opening tag file");
external_cleanup();
exit(1);
}
/* the old tag output file doesn't exist yet, just copy it over */
while (GetLine(new_tag_stream, line1, MAX_TAGFILE_LINE_LENGTH)) {
fprintf(output_stream, "%s\n", line1);
}
/* close the files */
fclose(new_tag_stream);
fclose(output_stream);
}
else {
/* create the required temporary file name */
tmp_filename = tempnam(".\\", "tg");
/* open the old tag file */
if ((input_stream = fopen(output_filename, "r")) ==
(FILE *) NULL) {
log_message("# MergeFile() -- error opening output file");
external_cleanup();
exit(1);
}
/* open the temporary file */
if ((output_stream = fopen(tmp_filename, "w")) ==
(FILE *) NULL) {
log_message("# MergeFile() -- error opening temporary file");
external_cleanup();
exit(1);
}
/* copy the output file to a temporary file and at the same time
* remove the old tags */
while (GetLine(input_stream, line1, MAX_TAGFILE_LINE_LENGTH)) {
/* only output the line if the line is non zero in length */
if (line1[0] != '\0') {
/* pass the first token on the line */
token_start = strpbrk(line1, delim);
while (strspn(token_start, delim)) {
token_start++;
}
/* get the length of the second token on the line */
token_length = strcspn(token_start, delim);
/* copy the name to a temporary variable */
strncpy(tag_filename, token_start, token_length);
tag_filename[token_length] = '\0';
/* if the token is not in argInput then output it */
if (!ArgIsMember(arglist, tag_filename)) {
fprintf(output_stream, "%s\n", line1);
}
}
}
/* close the open files */
fclose(input_stream);
fclose(output_stream);
/* remove the old tag file */
remove(output_filename);
/* open the temporary file for read */
if ((input_stream = fopen(tmp_filename, "r")) ==
(FILE *) NULL) {
log_message("# MergeFile() -- error opening input file");
external_cleanup();
exit(1);
}
/* open the new tags file for read */
if ((new_tag_stream = fopen(input_filename, "r")) ==
(FILE *) NULL) {
log_message("# MergeFile() -- error opening input file");
external_cleanup();
exit(1);
}
/* open the tag output file for write */
if ((output_stream = fopen(output_filename, "w")) ==
(FILE *) NULL) {
log_message("# MergeFile() -- error opening tag file");
external_cleanup();
exit(1);
}
/* merge the new tags in with the old tags */
file1ret = GetLine(new_tag_stream, line1, MAX_TAGFILE_LINE_LENGTH);
file2ret = GetLine(input_stream, line2, MAX_TAGFILE_LINE_LENGTH);
while (file1ret || file2ret) {
/* compare the lines and output in ascending order. If the
* command line specified no sorting then place the new tags
* first and then the old tags. This will result in slightly
* better performance for non-sorted tag finding algorithms
* assuming the last files tagged are the most likely to be used
* in the future */
if (file1ret && file2ret) {
if (flags->sort_tags) {
/* determine the sort order */
if (flags->case_sensitive)
compare = strcmp(line1, line2);
else
compare = stricmp(line1, line2);
/* if the new tag is less than or equal to the old tag
* then output the new tag */
if (compare <= 0) {
/* output the new tag and get another line */
fprintf(output_stream, "%s\n", line1);
file1ret = GetLine(new_tag_stream, line1,
MAX_TAGFILE_LINE_LENGTH);
}
else {
/* output the old tag and get another line */
fprintf(output_stream, "%s\n", line2);
file2ret = GetLine(input_stream, line2,
MAX_TAGFILE_LINE_LENGTH);
}
}
else {
/* just output from the new tag file and get another line */
fprintf(output_stream, "%s\n", line1);
file1ret = GetLine(new_tag_stream, line1,
MAX_TAGFILE_LINE_LENGTH);
}
}
else {
if (file2ret) {
/* new tag file is empty, just output line2, and get the
* next line in old tag file */
fprintf(output_stream, "%s\n", line2);
file2ret = GetLine(input_stream, line2,
MAX_TAGFILE_LINE_LENGTH);
}
else {
/* old tag file is empty, just output line1, and get the
* next line in new tag file */
fprintf(output_stream, "%s\n", line1);
file1ret = GetLine(new_tag_stream, line1,
MAX_TAGFILE_LINE_LENGTH);
}
}
}
/* close the open files */
fclose(input_stream);
fclose(new_tag_stream);
fclose(output_stream);
/* remove the temporary file and free tmp_filename memory */
remove(tmp_filename);
free(tmp_filename);
}
}